package com.xhj.mybatis.scripting.xmltags;

import java.util.List;

/**
 * ChooseSqlNode
 *
 * @author XJks
 * @description 用于在 MyBatis 的动态 SQL 语句中实现 <choose> 标签的逻辑。它会遍历一组 ifSqlNodes（对应 <when>），如果有一个条件成立就执行对应的 SQL 节点；如果都不成立，则执行 defaultSqlNode（对应 <otherwise>）。
 */
public class ChooseSqlNode implements SqlNode {
    /**
     * defaultSqlNode 表示 <otherwise> 节点，如果所有 <when> 条件都不满足，则执行它
     */
    private final SqlNode defaultSqlNode;

    /**
     * ifSqlNodes 是所有 <when> 节点的集合，每个 SqlNode 都代表一个条件分支
     */
    private final List<SqlNode> ifSqlNodes;

    /**
     * 构造方法，初始化 ifSqlNodes 和 defaultSqlNode
     *
     * @param ifSqlNodes     所有 <when> 节点的集合
     * @param defaultSqlNode <otherwise> 节点
     */
    public ChooseSqlNode(List<SqlNode> ifSqlNodes, SqlNode defaultSqlNode) {
        this.ifSqlNodes = ifSqlNodes;
        this.defaultSqlNode = defaultSqlNode;
    }

    /**
     * 实现 SqlNode 接口的 apply 方法，负责根据条件生成 SQL 片段
     *
     * @param context 动态 SQL 的上下文环境
     * @return 是否有节点被应用（true 表示有分支被执行）
     */
    @Override
    public boolean apply(DynamicContext context) {
        // 遍历所有 <when> 节点
        for (SqlNode sqlNode : ifSqlNodes) {
            // 如果某个 <when> 条件成立，则执行并返回 true
            if (sqlNode.apply(context)) {
                return true;
            }
        }
        // 如果所有 <when> 条件都不成立，且存在 <otherwise> 节点，则执行它
        if (defaultSqlNode != null) {
            defaultSqlNode.apply(context);
            return true;
        }
        // 如果没有任何分支被执行，则返回 false
        return false;
    }
}
